package com.llp.declaresystem.handler;

import com.llp.declaresystem.domain.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;
import java.sql.SQLException;
/**
 * @BelongsProject: declare-system
 * @BelongsPackage: com.llp.declaresystem.handler
 * @Author: bovan
 * @Date: 2022/11/26 17:44
 * @Description:
 */

/**
 * 全局异常处理
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 数字格式化异常
     * @param e
     * @return
     * @throws IOException
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = NumberFormatException.class)
    public Result handler(NumberFormatException e) throws  IOException{
        log.error("数字格式化异常:-------------->{}",e.getMessage());
        return new Result<>(400,e.getMessage(),null);
    }
    /**
     * 类型转换异常
     * @param e
     * @return
     * @throws IOException
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = ClassCastException.class)
    public Result handler(ClassCastException e) throws  IOException{
        log.error("类型转换异常:-------------->{}",e.getMessage());
        return new Result<>(400,e.getMessage(),null);
    }

    /**
     * 空指针异常
     * @param e
     * @return
     * @throws IOException
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = NullPointerException.class)
    public Result handler(NullPointerException e) throws  IOException{
        log.error("空指针异常:-------------->{}",e.getMessage());
        return new Result<>(400,e.getMessage(),null);
    }

    /**
     * 数组下标越界异常
     * @param e
     * @return
     * @throws IOException
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = ArrayIndexOutOfBoundsException.class)
    public Result handler(ArrayIndexOutOfBoundsException e) throws  IOException{
        log.error("数组下标越界异常:-------------->{}",e.getMessage());
        return new Result<>(400,e.getMessage(),null);
    }
    /**
     * 操作数据库异常
     * @param e
     * @return
     * @throws IOException
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = SQLException.class)
    public Result handler(SQLException e) throws  IOException{
        log.error("操作数据库异常:-------------->{}",e.getMessage());
        return new Result<>(400,e.getMessage(),null);
    }
    /**
     * 处理Assert的异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = IllegalArgumentException.class)
    public Result handler(IllegalArgumentException e) throws IOException {
        log.error("Assert异常:-------------->{}",e.getMessage());
        return new Result(400,e.getMessage(),null);
    }
    /**
     * @Validated 校验错误异常处理
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result handler(MethodArgumentNotValidException e) throws IOException {
        log.error("运行时异常:-------------->",e);
        BindingResult bindingResult = e.getBindingResult();
        ObjectError objectError = bindingResult.getAllErrors().stream().findFirst().get();
        return new Result(400,objectError.getDefaultMessage(),null);
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = RuntimeException.class)
    public Result handler(RuntimeException e) throws IOException {
        log.error("运行时异常:-------------->",e);
        return new Result(400,e.getMessage(),null);
    }
}
